package com.example.pro1.controller.zhao;


import com.google.gson.Gson;
import com.example.pro1.service.zhao.table.RefundInfoService;
import com.example.pro1.service.zhao.wxpay.WxPayService;
import com.example.pro1.util.zhao.HttpUtils;
import com.example.pro1.util.zhao.WechatPay2ValidatorForRequest;
import com.example.pro1.valu.R;
import com.example.pro1.valu.Standard;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@CrossOrigin//kuaiyu
@RestController
@RequestMapping("/api/wx-pay")
@Slf4j
@Api(tags = "微信支付")

public class WxPayController {

    @Resource
    private WxPayService wxPayService;
    @Resource
    private RefundInfoService refundsInfoService;
    @Resource
    private Verifier verifier;//public class ScheduledUpdateCertificatesVerifier implements Verifier??懂？哈哈哈



    @ApiOperation("微信native支付接口")
    //@PostMapping("native/{productId}/{userId}")
    @RequestMapping("/native/t1")
    public Standard nativePay(@RequestParam("productId") long productId,@RequestParam("userId") long userId,@RequestParam("fee") Integer fee,@RequestParam("num") String num,@RequestParam("beizhu") String beizhu,@RequestParam("addressId") String addressId)
    {
        log.info("发起支付请求");
        //返回二维码连接 and订单号
        Map<String,Object> map= null;
        try {
            map = wxPayService.nativePay(productId,"微信",userId,fee,num,beizhu,addressId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return R.ok().setData(map);

    }





    /**
     * 支付通知
     * 微信支付通过支付通知接口将用户支付成功消息通知给商户
     */
    @ApiOperation("支付通知处理函数")
    @PostMapping("/native/notify")
   /*
    商户系统收到支付结果通知，需要在 5秒内 返回应答报文，否则微信支付认为通知失败，后续会
    重复发送通知。*/
    public String nativeNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Gson gson = new Gson();
        Map<String, String> map = new HashMap<>();//应答对象
         //处理通知参数
        String body = HttpUtils.readData(request);

        Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
        String requestId=(String) bodyMap.get("id");//支付结果返回的为一requestid在body中不在头中先给他取出来，为实例化验签工具类做准备
        log.info("支付通知的id ===> {}", requestId);
        log.info("支付通知的完整数据 ===> {}", body);
        log.info("支付通知完整 ===> {}", request);

        //签名的验证
        WechatPay2ValidatorForRequest validator = new WechatPay2ValidatorForRequest(verifier, body, requestId);
        if (!validator.validate(request))
        {
            log.error("通知验签失败");
            //失败应答
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "通知验签失败");
            return gson.toJson(map);
        }
        //成功应答
        log.info("通知验签成功");
        response.setStatus(200);
        map.put("code", "SUCCESS");
        map.put("message", "成功");
        //TODO : 处理订单
        wxPayService.processOrder(bodyMap);
        return gson.toJson(map);
    }

    //取消订单
    @PostMapping("/cancel/{order_no}")
    public Standard cancelOrder(@PathVariable String order_no) throws Exception {
        log.info("取消订单");
        if(wxPayService.cancelOrder(order_no)>1)
            return R.ok();
        else
            return R.nonono();

    }

    //你不通知我自己求你
    @GetMapping("/serch/{order_no}")
    public Standard qurrey(@PathVariable String order_no) throws IOException {
        log.info("查询订单");
        String x=wxPayService.queryOrder(order_no);
        return  R.ok().data("ordermessage",x);
    }

    /**
     * 查询退款
     * @param refundNo
     * @return
     * @throws Exception
     */
    @ApiOperation("查询退款：测试用")
    @GetMapping("/query-refund/{refundNo}")
    public Standard queryRefund(@PathVariable String refundNo) throws Exception {
        log.info("查询退款");
        String result = wxPayService.queryRefund(refundNo);
        return R.ok().setMessage("查询成功").data("result", result);
    }

    @ApiOperation("申请退款")
    @PostMapping("/refunds/{orderNo}")
    public Standard refunds(@PathVariable String orderNo) throws Exception {
        log.info("申请退款");
        wxPayService.refund(orderNo);
        return R.ok();
    }



    @PostMapping("/refunds/notify")
    public String refundsNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Gson gson = new Gson();
        Map<String, String> map = new HashMap<>();//应答对象
        //处理通知参数
        String body = HttpUtils.readData(request);

        Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
        String requestId=(String) bodyMap.get("id");//支付结果返回的为一requestid在body中不在头中先给他取出来，为实例化验签工具类做准备
        log.info("退款通知的id ===> {}", requestId);
        log.info("退款通知的完整数据 ===> {}", body);
        log.info("退款通知完整 ===> {}", request);


        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");

        //签名的验证
        WechatPay2ValidatorForRequest validator = new WechatPay2ValidatorForRequest(verifier, body, requestId);
        if (!validator.validate(request))
        {
            log.error("通知验签失败");
            //失败应答
            response.setStatus(500);

            map.put("code", "ERROR");
            map.put("message", "通知验签失败");
            return gson.toJson(map);
        }
        //成功应答
        log.info("通知验签成功");
        response.setStatus(200);
        map.put("code", "SUCCESS");
        map.put("message", "成功");
        //TODO : 处理退单
        wxPayService.processRefund(bodyMap);

        return gson.toJson(map);
    }
}
